package kr.ac.ssu.ailab.Control;

import java.awt.Point;
import java.util.ArrayList;
import kr.ac.ssu.ailab.Control.CellControl;
import kr.ac.ssu.ailab.Control.MapControl;
import kr.ac.ssu.ailab.Model.Data.Cell;
import kr.ac.ssu.ailab.Model.Data.Cluster;
import kr.ac.ssu.ailab.View.SeqTest;

public class GraphUpdate
{
	private int mode;
	private Point point;
	private static GraphUpdate graphUpdate;
	private NewHeuristicPathFinding hueristic;
	private GraphControl graphControl;
	private double startTime;
	private double finishTime;

	/**
	 * 생성자
	 */
	public GraphUpdate()
	{
		this.mode = 0;
	}

	/**
	 * 어떠한 이벤트가 발생했는디 set 하는 메소드
	 * 
	 * @param mode
	 */
	public void setMode(int mode)
	{
		this.mode = mode;
	}

	/**
	 * 이벤트로 인한 경로 변경을 위해서 검색을 다시하기 위한 메소드
	 * 
	 * @param number
	 */
	public void rescan(int number)
	{

		NewHeuristicPathFinding nowHueristic = SeqTest.getFinding();
		graphControl = GraphControl.getInstance();
		ClusterControl CCInstance = ClusterControl.getInstance();

		Cell start = null;
		Point p = null;

		int num = 0;

		boolean isObstacle = true;

		switch (mode)
			{
			case MapControl.SET_FINISH:
				System.err.println("FINISH");

				start = nowHueristic.getFirst();
				start.setType(CellControl.START_CELL);

				hueristic = new NewHeuristicPathFinding();

				System.err.println("Start : " + start.getPosition());

				num = SeqTest.mapControl.getMapNumX() / CCInstance.getNumX();

				SeqTest.mapControl.setStartCell(start);

				CCInstance
						.setStartCluster(start.getPosition().x / num, start.getPosition().y / num);

				p = SeqTest.mapControl.getFinishCell().getPosition();
				CCInstance.setFinishCluster(p.x / num, p.y / num);

				graphControl.clearGraphParent();

				for (int i = 0; i < graphControl.getGoalList().size(); i++)
					graphControl.getGoalList().get(i).setType(CellControl.STAND_CELL);
				graphControl.setNuLLGoalList();
				graphControl.connectSFGraph();
				graphControl.reFindGraph(start);

				NewHeuristicPathFinding.setGoalList(graphControl.getGoalList());

				NewHeuristicPathFinding.change = false;

				hueristic.startSearch();
				break;
			case MapControl.SET_NORMAL:
			case MapControl.SET_HARD:
				isObstacle = false;
			case MapControl.SET_OBSTACLES:
			case MapControl.SET_THREATEN:
				if (isObstacle)
				{
					System.err.println("OBSTACLES or THREATEN");
				}

				startTime = System.currentTimeMillis();
				Cluster eventCluster = null;
				ArrayList<Cell> standCell = null;
				ArrayList<Cell> finishCellList = new ArrayList<Cell>();
				ArrayList<Integer> SeqList = new ArrayList<Integer>();

				eventCluster = CCInstance.getCluster(number);

				standCell = eventCluster.getStandCell();

				Cluster[] adjacentCluster = CCInstance.getAdjacentCluster(eventCluster);

				SeqList.add(number);

				graphControl.clearGraphParent();

				for (int i = 0; i < adjacentCluster.length; i++)
				{
					SeqList.add(adjacentCluster[i].getSeqCluster());
					finishCellList.addAll(adjacentCluster[i].getStandCell());
				}

				for (int i = 0; i < adjacentCluster.length; i++)
				{
					graphControl.removeEdgeLv1(standCell.get(0), finishCellList.get(i));
					graphControl.removeEdgeCost(standCell.get(0), finishCellList.get(i));
				}

				CCInstance.createPartialCandiCSC(number);
				ClusterSearch clusterSearch = new ClusterSearch();

				clusterSearch.repartialSearch(SeqList);

				finishTime = System.currentTimeMillis();

				System.err.println("COST : " + (finishTime - startTime));
				start = nowHueristic.getFirst();
				start.setType(CellControl.START_CELL);

				hueristic = new NewHeuristicPathFinding();

				System.err.println("Start : " + start.getPosition());

				num = SeqTest.mapControl.getMapNumX() / CCInstance.getNumX();

				SeqTest.mapControl.setStartCell(start);

				CCInstance
						.setStartCluster(start.getPosition().x / num, start.getPosition().y / num);

				for (int i = 0; i < graphControl.getGoalList().size(); i++)
					graphControl.getGoalList().get(i).setType(CellControl.STAND_CELL);

				graphControl.setNuLLGoalList();

				graphControl.connectSFGraph();

				graphControl.reFindGraph(start);

				if (graphControl.getGoalList().isEmpty())
				{
					System.err.println("00000000000000000000000");
				}
				NewHeuristicPathFinding.setGoalList(graphControl.getGoalList());

				NewHeuristicPathFinding.change = false;

				hueristic.startSearch();

				break;

			default:
				System.err.println("MODE : " + mode);
				break;

			}

	}

	/**
	 * 어떠한 지점에서 이벤트가 발생했는지 알기 위한 메소드
	 * 
	 * @param point
	 */
	public void setPoint(Point point)
	{
		this.point = point;
	}

}
